/**
 ******************************************************************************
 * @file	watch_opm.c
 * @brief	TR700光功率计测试与使用
 *
 * @section Platform
 * 	-#
 * @section Library
 * -# spidev.ko
 * -# libstm32-spi.so
 *
 * - 2017-6-22,MenglongWu,MenglongWoo@aliyun.com
 *
 * Copyright (C) 2017 桂林聚联科技有限公司, Inc. All Rights Reserved.
 */
#include <stdio.h>
#include <string.h>

#include "printl.h"
#include <math.h>
#include <unos_input.h>
#include <cui.h>

#include "stm32-spi.h"
#include "any-chip.h"


#define CUI_SELECT    (C_CYAN AC_REVERSE)
#define CUI_NORMAL    (C_NORMAL)
#define CUI_HIGHLIGHT (C_CYAN)
/*
   ADC:1108  (-65.15dBm)  <1k>  |  Auto  LV <1>
                  -         -      ^         ^-
*/

struct _watch_opm_private
{
    int            *isdebug;
    unsigned short *adc;
    float	  *dbm;
    unsigned int   *mode;
    int            *lv;
};


#define COUNT_CONTROL (2)
static void _draw(unsigned int select, void *v)
{
    struct _watch_opm_private *p                     = (struct _watch_opm_private *)v;
    char                      *c_item[COUNT_CONTROL] = { C_NORMAL, C_NORMAL };
    char                      *pstrdebug[]           = { "Auto", "Debug" };
    char                      *strmode[]             = { "cw", "270", "1k", "2k" };  // TODO off
    char                      *pdebug;
    char                      *pmode;


    c_item[select % ARRAY_SIZE(c_item)] = (C_CYAN AC_REVERSE);  // 高亮选中列

    pdebug = pstrdebug[*(p->isdebug) % sizeof(*pstrdebug)];
    pmode  = strmode[*(p->mode) % sizeof(*strmode)];


    printf("ADC:%4d  "
           "(%6.2fdBm)  "
           "<%s>  "
           "|  "
           "%s%6s   " C_NORMAL
           "LV %s<%d>\r" C_NORMAL,
           *(p->adc),
           *(p->dbm),
           pmode,
           c_item[0],
           pdebug,
           c_item[1],
           *(p->lv));
}

static void _key_process(unsigned int *select, void *v, int key)
{
    struct _watch_opm_private *p    = (struct _watch_opm_private *)v;
    int                        deta = 1;

    switch (key) {
    case VK_DOWN:
    case 's':
	deta = -deta;
    case VK_UP:
    case 'w':
	switch ((unsigned int)(*select) % COUNT_CONTROL) {
	case 0:  // auto/debug
	    *(p->isdebug) = !*(p->isdebug);
	    break;
	case 1:  // lv
	    if (*(p->isdebug)) {
		*(p->lv) += deta;
		if (*(p->lv) > 7) {
		    *(p->lv) = 1;
		}
		else if (*(p->lv) < 1) {
		    *(p->lv) = 7;
		}
	    }
	    break;
	default:
	    break;
	}
	break;
    case VK_RIGHT:
    case 'd':
	(*select)++;
	break;
    case VK_LEFT:
    case 'a':
	(*select)--;
	break;
    default:
	break;
    }
}


#define TASK_DETA_READKEY  (20 * _1MS)
#define TASK_DETA_AUTO_OPM (500 * _1MS)


void watch_opm(struct stm32_spi_dev *dev)
{
    // 1000 * COUNT_CONTROL 多少都无所谓，只不过如果设置为0
    unsigned int  select = 1000 * COUNT_CONTROL;
    int           key    = 0;
    unsigned long task_readkey;
    unsigned long task_auto_opm;


    int            isdebug = 0;
    unsigned short adc     = 0;
    float          dbm     = 0;
    unsigned int   mode    = 0;
    int            lv      = 0;
    short          wave    = 0;

    struct _watch_opm_private draw;
    struct tr700_getopm       input;

    stm_getopm(dev, &input);
    wave = input.wave;
    dbm  = input.dbm;
    mode = input.mode;

    draw.isdebug = &isdebug;
    draw.adc     = &adc;
    draw.dbm     = &dbm;
    draw.mode    = &mode;
    draw.lv      = &lv;
    _draw(select, &draw);

    printf(C_CYAN
           "[q]:Quit  ['w'/up , 's'/down]:Edit  "
           "['a'/left , 's'/right']:move cursor \r\n" C_NORMAL);

    task_readkey  = jiffies + TASK_DETA_READKEY;
    task_auto_opm = jiffies + TASK_DETA_AUTO_OPM;
    setvbuf(stdout, "", _IONBF, 0);
    // set_keypress();
    // kbhit();
    while (key != 'q') {
	key = 0;
	if (time_after(jiffies, task_readkey)) {
	    task_readkey = jiffies + TASK_DETA_READKEY;
	    // key = getkeycode();
	    // key = getchar();
	    if (key > 0) {
		_key_process(&select, &draw, key);
		_draw(select, &draw);
		// Ctrl_OPM_SW(lv);
	    }
	}

	if (time_after(jiffies, task_auto_opm)) {
	    task_auto_opm = jiffies + TASK_DETA_AUTO_OPM;
	    stm_getopm(dev, &input);
	    wave = input.wave;
	    dbm  = input.dbm;
	    mode = input.mode;
	    _draw(select, &draw);
	}
    }
    printf("\r\n");
}
